import hashlib
import hmac
import os
import time
import uuid
import json
import base64
import requests
from datetime import datetime, timezone
from core.providers.tts.base import TTSProviderBase


class TTSProvider(TTSProviderBase):
    def __init__(self, config, delete_audio_file):
        super().__init__(config, delete_audio_file)
        self.appid = config.get("appid")
        self.secret_id = config.get("secret_id")
        self.secret_key = config.get("secret_key")
        self.voice = config.get("voice")
        self.api_url = "https://tts.tencentcloudapi.com"  # 正确的API端点
        self.region = config.get("region")
        self.output_file = config.get("output_dir")

    def _get_auth_headers(self, request_body):
        """生成鉴权请求头"""
        # 获取当前UTC时间戳
        timestamp = int(time.time())
        
        # 使用UTC时间计算日期
        utc_date = datetime.fromtimestamp(timestamp, tz=timezone.utc).strftime('%Y-%m-%d')
        
        # 服务名称必须是 "tts"
        service = "tts"
        
        # 拼接凭证范围
        credential_scope = f"{utc_date}/{service}/tc3_request"
        
        # 使用TC3-HMAC-SHA256签名方法
        algorithm = "TC3-HMAC-SHA256"
        
        # 构建规范请求字符串
        http_request_method = "POST"
        canonical_uri = "/"
        canonical_querystring = ""
        
        # 请求头必须包含host和content-type，且按字典序排列
        canonical_headers = (
            f"content-type:application/json\n"
            f"host:tts.tencentcloudapi.com\n"
        )
        signed_headers = "content-type;host"
        
        # 请求体哈希值
        payload = json.dumps(request_body)
        payload_hash = hashlib.sha256(payload.encode('utf-8')).hexdigest()
        
        # 构建规范请求字符串
        canonical_request = (
            f"{http_request_method}\n"
            f"{canonical_uri}\n"
            f"{canonical_querystring}\n"
            f"{canonical_headers}\n"
            f"{signed_headers}\n"
            f"{payload_hash}"
        )
        
        # 计算规范请求的哈希值
        hashed_canonical_request = hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
        
        # 构建待签名字符串
        string_to_sign = (
            f"{algorithm}\n"
            f"{timestamp}\n"
            f"{credential_scope}\n"
            f"{hashed_canonical_request}"
        )
        
        # 计算签名密钥
        secret_date = self._hmac_sha256(f"TC3{self.secret_key}".encode('utf-8'), utc_date)
        secret_service = self._hmac_sha256(secret_date, service)
        secret_signing = self._hmac_sha256(secret_service, "tc3_request")
        
        # 计算签名
        signature = hmac.new(
            secret_signing, 
            string_to_sign.encode('utf-8'), 
            hashlib.sha256
        ).hexdigest()
        
        # 构建授权头
        authorization = (
            f"{algorithm} "
            f"Credential={self.secret_id}/{credential_scope}, "
            f"SignedHeaders={signed_headers}, "
            f"Signature={signature}"
        )
        
        # 构建请求头
        headers = {
            "Content-Type": "application/json",
            "Host": "tts.tencentcloudapi.com",
            "Authorization": authorization,
            "X-TC-Action": "TextToVoice",
            "X-TC-Timestamp": str(timestamp),
            "X-TC-Version": "2019-08-23",
            "X-TC-Region": self.region,
            "X-TC-Language": "zh-CN"
        }
        
        return headers
    
    def _hmac_sha256(self, key, msg):
        """HMAC-SHA256加密"""
        if isinstance(msg, str):
            msg = msg.encode('utf-8')
        return hmac.new(key, msg, hashlib.sha256).digest()

    def generate_filename(self, extension=".wav"):
        return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")

    async def text_to_speak(self, text, output_file):
        # 构建请求体
        request_json = {
            "Text": text,  # 合成语音的源文本
            "SessionId": str(uuid.uuid4()),  # 会话ID，随机生成
            "VoiceType": int(self.voice),  # 音色
        }

        try:
            # 获取请求头（每次请求都重新生成，以确保时间戳和签名是最新的）
            headers = self._get_auth_headers(request_json)
            
            # 发送请求
            resp = requests.post(self.api_url, json.dumps(request_json), headers=headers)
            
            # 检查响应
            if resp.status_code == 200:
                response_data = resp.json()
                
                # 检查是否成功
                if response_data.get("Response", {}).get("Error") is not None:
                    error_info = response_data["Response"]["Error"]
                    raise Exception(f"API返回错误: {error_info['Code']}: {error_info['Message']}")
                
                # 提取音频数据
                audio_data = response_data["Response"].get("Audio")
                if audio_data:
                    # 解码Base64音频数据并保存
                    with open(output_file, "wb") as f:
                        f.write(base64.b64decode(audio_data))
                else:
                    raise Exception(f"{__name__}: 没有返回音频数据: {response_data}")
            else:
                raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}")
        except Exception as e:
            raise Exception(f"{__name__} error: {e}")